﻿/********************************************************
 * Module Name    : User Control
 * Project Name   : VFrameworkWeb
 * Control Name   : VNumTextBox
 * Purpose        : To create a Text Box Control which takes only 
                    Integer Value in it. According to the calture 
 * NameSpace Used : VAdvantage.Controls
 * Class Used     : VNumTextBox which inherits the Default TextBox and Control Interface
 * Chronological    Development
 * Mukesh Arora      14-Oct-2008 
  ******************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using VAdvantage.Classes;
using System.Windows;
using System.Windows.Media;
using System.Windows.Input;
using System.Windows.Data;
namespace VAdvantage.Controls
{
    public class VNumTextBox : CTextBox, IControl, ITextChangedEvent
    {
        #region  Private variables

        private const int _MAXLENGTH = 50; // set the text box length as input length
        private const int WM_CHAR = 0x0102; // char key message
        //private const int WM_CUT = 0x0300;  // mouse message in ContextMenu on right Click
        //private const int WM_COPY = 0x0301;// mouse message in ContextMenu
        //private const int WM_PASTE = 0x0302;// mouse message in ContextMenu
        //private const int WM_CLEAR = 0x0303;// mouse message in ContextMenu
        string str, str1, str2;//variable to store the text of textbox
        private int _decimalLength = 0;//set decimal length
        private bool _allowNegative = true;//allow decimal key
        private string _valueFormatStr = string.Empty;//get value in string formate
        private char _decimalSeparator = '.';//check decimal variable
        private char _negativeSign = '-';//To include -ve sign in text box
        private bool isChanged = true;
        private bool isSelected = false;
        private Format _format = null;
        private String _columnName;//column name
        protected int _displayType;	//  Currency / UoM via Context
        //private DecimalFormat m_format;
        private String _title;
        private bool _setting;
        private String _oldText;
        private String _initialText;
        private bool _rangeSet = false;
        private Double _minValue;//minimum value
        private Double _maxValue;//maximum value
        private bool _modified = false;
        private Grids.GridField _field = null;
        private bool _mandatory;//mendatory field status
        private bool _readOnly;//read only status
        private bool _textSetting = false;

        Binding binding;

        private bool _focus;

        #endregion


        #region Property

        public static readonly DependencyProperty TextValueProperty =
         DependencyProperty.Register("TextValue", typeof(int?), typeof(VAdvantage.Controls.VNumTextBox), new PropertyMetadata((o, e) =>
         {
             ((VNumTextBox)o).SetTextValue((int?)e.NewValue);

         }));


        public int? TextValue
        {
            get
            {
                return ((int?)GetValue(VNumTextBox.TextValueProperty));
            }
            set
            {
                SetValue(VNumTextBox.TextValueProperty, value);
            }
        }

        void SetTextValue(int? newVal)
        {
            //TextValue = newVal;
            int? id = null;
            if (newVal == null)
            {
                this.Text = "";
            }
            else
            {
                this.Text = _format.GetFormatedValue(Decimal.Parse(newVal.ToString()));
            }
            //SetGetValue(id, false);


        }


        #endregion




        public event EventHandler VetoableChangeListener;
        public event EventHandler FireTextChanged;


        public VNumTextBox()
        {

            try
            {

                //this.TextChanged += new TextChangedEventHandler(VNumTextBox_TextChanged);
                
                //Set default text of textbox
                this.Text = "0";

             
                //Set the string formate
                this.SetValueFormatStr();
            }
            catch (Exception ex)
            {
                return;
            }

        }

       

        /// <summary>
        /// Parametrised Constructor
        /// </summary>
        /// <param name="columnName">Displayed column name</param>
        /// <param name="mandatory">Bool Type(mendatory status)</param>
        /// <param name="isReadOnly">Bool Type(readonly status)</param>
        /// <param name="isUpdateable">Bool type(is update able)</param>
        /// <param name="displayType">display Integer value</param>
        /// <param name="title">set title</param>
        public VNumTextBox(String columnName, bool mandatory, bool isReadOnly, bool isUpdateable,
                        int displayType, String title):base()
        {
            try
            {
                //InitializeComponent();
                //No multiline on textbox

               

                base.TextAlignment = TextAlignment.Right;
                //base.TextAlign = HorizontalAlignment.Right;
                
              
                //Set the string formate
                this.SetValueFormatStr();

                //this.Name = columnName;
                _columnName = columnName;
                _title = title;
                _displayType = displayType;
                _mandatory = mandatory;
                if (isReadOnly || !isUpdateable)
                {
                    //this.Enabled = false;
                    SetReadOnly(true);
                    //this.ContextMenu = new ContextMenu();
                }
                else
                {
                    SetReadOnly(false);
                }

                //make a format object
                _format = DisplayType.GetNumberFormat(displayType);
                this.MaxLength = 10;
                
                _maxValue = Int32.MaxValue;

                this.TextChanged += VNumTextBox_TextChanged;

                //this.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.Never;
            }
            catch (Exception ex)
            {
                return;
            }
        }

        

        void VNumTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {

            ////this.OnTextChanged(e);
            //// base.OnTextChanged(e);
            //if (_textSetting)
            //    return;
            //if (EditingControlDataGridView != null)
            //{
            //    EditingControlValueChanged = true;
            //    EditingControlDataGridView.NotifyCurrentCellDirty(true);
            //    EditingControlDataGridView.CurrentCell.Value = this.GetValue();
            //}
            SetColor();
            //if (isChanged)
            //{
            //    base.OnTextChanged(e);
            //    if (FireTextChanged != null)
            //    {
            //        FireTextChanged(this, e);
            //    }
            //}
        }

        private bool IsTextChanged()
        {
            try
            {
                return _field.GetValue().ToString() != Decimal.Parse(this.Text).ToString();
            }
            catch
            {
                return true;
            }
        }

       
     



       

        protected override void OnGotFocus(RoutedEventArgs e)
        {
            
            base.OnGotFocus(e);
            _focus = true;

            if (!isSelected)
            {
                this.SelectAll();
                isSelected = true;
            }
        }

        /// <summary>
        /// Event fiers when textbox lost focus
        /// set the textbox value According to the calture
        /// also check entered text formate
        /// </summary>
        /// <param name="e">control leave argument</param>
        protected override void  OnLostFocus(RoutedEventArgs e)
        {
 	        isChanged = false;
            if (this.Text.ToString().Trim() == "" || this.Text.ToString().Trim() == "-")
            {
                this.Text = "";

            }
            isSelected = false;

            //update by Mukesh on date 19, April 2010
            //bug Resolve on enter any value it change to min or max value so call it onLeave event before that it 
            //call OnKeyPress Event
            if (_rangeSet)
            {
                try
                {
                    double val = Convert.ToDouble(this.Text);
                    if (val < _minValue)
                    {
                        this.Text = _minValue.ToString();
                    }
                    else
                        if (val > _maxValue)
                        {
                            this.Text = _maxValue.ToString();
                        }
                }
                catch
                {
                }
            }

            try
            {
                double val = Convert.ToDouble(this.Text);
                if (val > double.Parse(Int32.MaxValue.ToString()))
                {
                    this.Text = Int32.MaxValue.ToString();
                }

            }
            catch
            {
            }


            //end update by mukesh 




            //Assigh the Formated the value 


            if (_format != null && this.Text != "")                         //to remove format char from string (like ,or,3)    
                this.Text = _format.GetFormatedValue(Decimal.Parse(this.Text));// string.Format(_format.GetFormat(), _format.SetIntDigit(this.Text));

            //if (EditingControlDataGridView == null && IsTextChanged()) commented for SL
            if (IsTextChanged())
            {
                if (VetoableChangeListener != null)
                {
                    VetoableChangeListener(this, e);
                }
            }
            isChanged = true;
            base.OnLostFocus(e);
            if (IsReadOnly)
            {
                SetBackGround(true);
            }
            _focus = false;
        }
      
      

        #region  custom private methods

        #region textFormate Metod
        /// <summary>
        /// Method used to set
        /// the text formate in the textbox 
        /// </summary>
        private void SetValueFormatStr()
        {
            //store the text formate in the variable
            _valueFormatStr = "F" + _decimalLength.ToString();
        }
        #endregion

        #region SendCharKey()
       
        /// <summary>
        /// Handel the string message
        /// on Cut,Copyand Past in text box
        /// </summary>
        /// <param name="charKey">Charactor key value</param>
       //commented for SL
        //private void SendCharKey(char charKey)
        //{
        //    //create instance of message
        //    Message msg = new Message();
        //    //use handle
        //    msg.HWnd = this.Handle;
        //    //message contains Charector String
        //    msg.Msg = WM_CHAR;
        //    //set the pointer
        //    msg.WParam = (IntPtr)charKey;
        //    //only put zero in textbox
        //    msg.LParam = IntPtr.Zero;
        //    //this method
        //    this.WndProc(ref msg);
        //}
        #endregion

      

        #region IsSeparator bool method for index
        /// <summary>
        /// This is bool type method set index text
        /// </summary>
        /// <param name="index">text index</param>
        /// <returns>bool Type</returns>
        private bool IsSeparator(int index)
        {
            try
            {
                //return index
                return this.IsSeparator(this.Text[index]);
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        #endregion

        #region IsSeparator bool method for Chacrecto
        /// <summary>
        /// This is a bool type method for decimal seprator
        /// </summary>
        /// <param name="decimalChar">decimal key value</param>
        /// <returns>bool status(True/False)</returns>
        private bool IsSeparator(char decimalChar)
        {
            try
            {
                //if charector is decimal
                if (decimalChar == _decimalSeparator)
                {
                    //return in the textbox
                    return true;
                }
                else
                {
                    //other wise no return
                    return false;
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        #endregion
        #endregion

        #region IControl

        /// <summary>
        /// mendatory fields
        /// </summary>
        /// <returns>Bool type</returns>
        public bool GetIsMandatory()
        {
            return _mandatory;
        }
        /// <summary>
        /// Sets Mandatory
        /// </summary>
        /// <param name="value">bool type value</param>
        public void SetIsMandatory(bool value)
        {
            _mandatory = value;
        }
        public string GetSelectedText()
        {
            return this.SelectedText;
        }

        /// <summary>
        /// read only fields
        /// </summary>
        /// <returns>Bool type(read only status)</returns>
        public bool GetIsReadonly()
        {
            return _readOnly;
        }
        /// <summary>
        /// get field from Model.GridField class 
        /// </summary>
        /// <returns>class fields</returns>
        public Grids.GridField GetField()
        {
            return _field;
        }
        /// <summary>
        /// set the field from Model.GridField
        /// </summary>
        /// <param name="field">set field of Model.GridField class</param>
        public void SetField(Grids.GridField field)
        {
            _field = field;
        }
        /// <summary>
        /// display type
        /// </summary>
        /// <returns>Disply value</returns>
        public int GetDisplayType()
        {
            return _displayType;
        }
        /// <summary>
        /// set display type
        /// </summary>
        /// <param name="displayType">set disply value</param>
        public void SetDisplayType(int displayType)
        {
            _displayType = displayType;
        }
        /// <summary>
        /// get control name
        /// </summary>
        /// <returns>column name</returns>
        public string GetName()
        {
            return this._columnName;
        }
        /// <summary>
        /// get control value
        /// </summary>
        /// <returns>control value</returns>
        /// Harwinder
        /// ***dont-write
        public object GetValue()
        {
            if (this.Text.Trim() == "" || this.Text.Trim() == "-")
            { return null; }

            try { return decimal.Parse(this.Text.Trim()); }
            catch { return null; }
        }
       // private bool _textSetting = false;

        /// <summary>
        /// property bind to data
        /// </summary>
        //Commented for SL
        //public object BindValue  
        //{
        //    get { return GetValue(); }
        //    set
        //    {
        //        _textSetting = true;

        //        if (value == DBNull.Value)
        //        {

        //            Text = "";
        //        }
        //        else if (Text != _format.GetFormatedValue(value) && Text != value.ToString())//ring.Format(_format.GetFormat(),value))
        //        {
        //            this.Text = _format.GetFormatedValue(value);
        //        }
        //        SetColor();
        //        _textSetting = false;
        //    }
        //}
        /// <summary>
        /// Set value
        /// </summary>
        /// <param name="value">value</param>
        public void SetValue(object value)
        {
            if (value == null)
                this.Text = "";
            else
                this.Text = _format.GetFormatedValue(value);
        }

        /// <summary>
        /// get control text
        /// </summary>
        /// <returns>Control text</returns>
        public string GetText()
        {
            return this.Text.Trim();
        }


        private SolidColorBrush backColorBrush = new SolidColorBrush();

        public void SetReadOnly(bool readOnly)
        {
            _readOnly = readOnly;
            this.IsReadOnly = readOnly;
            this.IsTabStop = !readOnly;
            SetBackGround(readOnly);
        }

        public void SetBackGround(bool value)
        {
            if (value)
            {
                backColorBrush.Color = DataBase.GlobalVariable.READONLY_TEXT_BACK_COLOR;
                this.Background = backColorBrush;
            }
            else
            {
                backColorBrush.Color = DataBase.GlobalVariable.NORMAL_TEXT_BACK_COLOR;
                this.Background = backColorBrush;
                SetColor();
            }
        }

        private void SetColor()
        {
            if (_mandatory)
            {
                if (this.Text == "")
                {
                    backColorBrush.Color = DataBase.GlobalVariable.MANDATORY_TEXT_BACK_COLOR;
                    this.Background = backColorBrush;
                }
                else
                {
                    backColorBrush.Color = DataBase.GlobalVariable.NORMAL_TEXT_BACK_COLOR;
                    this.Background = backColorBrush;
                    if (_field != null)
                        _field.SetError(false);
                }
            }
        }



      
        #endregion

        /// <summary>
        /// set the text range
        /// </summary>
        /// <param name="minValue"> set the minimum value</param>
        /// <param name="maxValue">set maximum value</param>
        /// <returns>bool type(for range set)</returns>
        public bool SetRange(string minValue, string maxValue)
        {
            if (minValue == null || maxValue == null || minValue == "" || minValue == "")
                return false;
            try
            {
                _minValue = Convert.ToDouble(minValue);
                _maxValue = Convert.ToDouble(maxValue);
            }
            catch (FormatException fex)
            {
                return false;
            }
            _rangeSet = true;
            return _rangeSet;
        }



        # region OnKeyDown
        protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e)
        {
            //base.OnKeyDown(e);
            try
            {
                Key inputKey = e.Key;
                if (e.PlatformKeyCode == 189)
                    inputKey = Key.Subtract;

                string s = "1234567890\b";
                isChanged = false;
                //this.OnKeyPress(e);
                //on keyPress readonly
                if (this.IsReadOnly)
                {
                    return;//return false
                }

                ////check decimal length and decimal seprator //we restict here
                if (_decimalLength == 0 && inputKey == Key.Decimal)
                {
                    //enable the handler
                    e.Handled = true;
                    //return the value
                    return;
                }
                //allow -ve sign
                if (!_allowNegative && inputKey == Key.Subtract && this.Text.IndexOf(_negativeSign) < 0)
                {
                    //enable the handler
                    e.Handled = true;
                    //return the value
                    base.OnKeyDown(e);
                    return;
                }
                //if Key Press not a charector,not a -ve sign and not a dot
                else if (!CheckInputKey(inputKey) && inputKey != Key.Subtract && inputKey != Key.Decimal)
                {
                    //enable the handler
                    e.Handled = true;
                    //return the value
                    base.OnKeyDown(e);
                    return;
                }

                //check the condition on -ve value
                bool isNegative = false;
                if (this.Text.Length > 0)
                    isNegative = (this.Text[0] == _negativeSign) ? true : false;


                //place -ve sign and the starting potion
                if (isNegative && this.SelectionStart == 0)
                {
                    //set the position for -ve sign
                    this.SelectionStart = 1;
                }
                //if pressed -ve
                if (inputKey == Key.Subtract)
                {
                    //store the -ve 
                    int selStart = this.SelectionStart;
                    //not -ve sign this is [logic to covert -ve to positive]
                    if (!isNegative)
                    {
                        //plce -ve with text

                        this.Text = _negativeSign + this.Text;


                        //set the cursor postion
                        this.SelectionStart = selStart + 1;
                    }
                    else
                    {
                        //to remove -ve sign set the length for text and cursor

                        this.Text = this.Text.Substring(1, this.Text.Length - 1);

                        //if selected text is greater then one
                        if (selStart >= 1)
                        {
                            //set Cursor
                            this.SelectionStart = selStart - 1;
                        }
                        else
                        {
                            //other set to 0
                            this.SelectionStart = 0;
                        }
                    }
                    // minus(-) has been handled
                    e.Handled = true;
                    //return nothing in the string
                    base.OnKeyDown(e);
                    return;
                }

                //check for the textbox value
                if (this.Text == "0")
                {
                    //palce cursor on current postion
                    this.SelectionStart = 0;
                    // replace thre first char, ie. 0
                    this.SelectionLength = 1;
                }
                //when text contain -0 
                else if (this.Text == _negativeSign + "0")
                {
                    //set cursor on current postion
                    this.SelectionStart = 1;
                    // replace thre first char, ie. 0
                    this.SelectionLength = 1;
                }
                //check for decimal length
                else if (_decimalLength > 0)
                {


                }
                //set isChange to true for call function to change toolbar icon
                isChanged = true;
                base.OnKeyDown(e);
            }
            catch (Exception ex)
            {
                return;
            }

        }

        private bool CheckInputKey(Key k)
        {

            bool retVal = false;

            if ((k >= Key.D0 && k <= Key.D9) || (k >= Key.NumPad0 && k <= Key.NumPad9))
            {
                retVal = true;
            }

            //check for backspace, tab, up, down, left, right keys
            //if ((k == Key.Back) || (k == Key.Tab) || (k == Key.Left || k == Key.Right || k == Key.Up || k == Key.Down))
            //{
            //    retVal = true;
            //}
            if ((k == Key.Back) || (k == Key.Tab) || (k == Key.Left || k == Key.Right || k == Key.Up || k == Key.Down||k==Key.Delete))      
            {
                retVal = true;
            }

            return retVal;
        }

        #endregion 

        protected override void OnKeyUp(KeyEventArgs e)
        {
            //isChanged = false;
            if (e.Key == Key.Enter)
            {
                isChanged = true;
            }
            if (isChanged)
            {
                //commented for SL
                //if (EditingControlDataGridView == null && e.KeyCode == Keys.Enter)
                if (e.Key == Key.Enter)
                {
                    if (VetoableChangeListener != null)
                        VetoableChangeListener(this, e);
                }
                else
                {
                    if (FireTextChanged != null)
                    {
                        FireTextChanged(this, EventArgs.Empty);
                    }
                }
            }
        }
    
     public void SetAtttribute(Grids.GridField field)
        {
            // this.KeyUp -= new KeyEventHandler(VAmountTextBox_KeyUp);


            _columnName = field.GetColumnName();
            _displayType = field.GetDisplayType();
            _format = DisplayType.GetNumberFormat(_displayType);
            SetField(field);

            // this.KeyUp +=new KeyEventHandler(VAmountTextBox_KeyUp);

        }

      

        /// <summary>
        /// process key board key's message
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        //commented for SL
        //protected override bool ProcessKeyMessage(ref Message m)
        //{
        //    bool b = base.ProcessKeyMessage(ref m);
        //    /* to resolve special char like (#,!,& etc) accept problrm in datagridview editing control*/
        //    if (b && EditingControlDataGridView != null)
        //    {
        //        return ProcessKeyEventArgs(ref m);
        //    }
        //    return b;
        //}

        public bool IsDisabled()
        {
            return !this.IsEnabled;
        }

        public void SetDisabled(bool disabled)
        {
            this.IsEnabled = !disabled;
        }

        //public bool IsReadonly()
        //{
        //    return this.IsReadOnly;
        //}

        //public void SetReadonly(bool ro)
        //{
        //    this.IsReadOnly = ro;
        //}

        public void SetName(string name)
        {
            this._columnName = name;
        }

        public void SetText(string value)
        {
            this.Text = value;
        }

        public int GetTabIndex()
        {
            return this.TabIndex;
        }

        public void SetTabindex(int tabindex)
        {
            this.TabIndex = tabindex;
        }

        public bool Multiline
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }
       

        public void SetEnabled(bool enabled)
        {
            this.IsEnabled = enabled;
        }

        public void  SetVisible(bool visible)
        {
            this.Visibility = visible ?System.Windows.Visibility.Visible:System.Windows.Visibility.Collapsed;
        }

        public bool Visible
        {
            get
            {
                return System.Windows.Visibility.Visible == this.Visibility;
            }
            set
            {
                this.Visibility =value? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
            }
        }

        public bool Focused
        {
            get { return _focus; }
        }

        public void Dispose()
        {
            //base.Dispose(disposing);
            _field = null;
            VetoableChangeListener = null;
            FireTextChanged = null;
            binding = null;
        }


        public string BindValue
        {
            set 
            {
                binding = new Binding(value);
                binding.Mode = BindingMode.OneWay;
                this.SetBinding(VNumTextBox.TextValueProperty, binding);

            
            }
        }


     
    }
}
